import { computed } from 'vue'
import { storeToRefs } from "pinia"
import { nanoid } from "nanoid"
import { message } from 'ant-design-vue'
import { Slide } from "@/types/slides"
import { useSlidesStore } from "@/store/slides"
import { useMainStore } from "@/store/main"
import useHistorySnapshot from "./useHistorySnapshot"
import usePasteTextClipboardData from "./usePasteTextClipboardData"
import useAddSlidesOrElements from './useAddSlidesOrElements'
import { encrypt } from '@/utils/crypto'
import { createElementIdMap } from "@/utils/element"
import { readClipboard, copyText } from '@/utils/clipboard'
import { KEYS } from '@/configs/hotkey'

export default () => {
  const slidesStore = useSlidesStore()
  const { theme, slides, slideIndex, currentSlide } = storeToRefs(slidesStore)
  const mainStore = useMainStore()
  const { selectedSlidesIndex: _selectedSlidesIndex, activeElementIdList } = storeToRefs(mainStore)

  const { addHistorySnapshot } = useHistorySnapshot()
  const { pasteTextClipboardData } = usePasteTextClipboardData()

  const selectedSlidesIndex = computed(() => [..._selectedSlidesIndex.value, slideIndex.value])
  const selectedSlides = computed(() => slides.value.filter((_, index) => selectedSlidesIndex.value.includes(index)))
  const selectedSlidesId = computed(() => selectedSlides.value.map(item => item.id))

  const { addSlidesFromData } = useAddSlidesOrElements()
  // 重置幻灯片
  const resetSlides = () => {
    const emptySlide: Slide = {
      id: nanoid(10),
      elements: [],
      background: {
        type: 'solid',
        color: theme.value.backgroundColor
      }
    }
    mainStore.setActiveElementIdList([])
    slidesStore.updateSlideIndex(0)
    slidesStore.setSlides([emptySlide])
  }

  // 创建一页空白页并添加到下一页
  const createSlide = () => {
    const emptySlide: Slide = {
      id: nanoid(10),
      elements: [],
      background: {
        type: 'solid',
        color: theme.value.backgroundColor
      }
    }
    mainStore.setActiveElementIdList([])
    // 添加新的幻灯片页面
    slidesStore.addSlide(emptySlide)
    // 添加历史快照
    addHistorySnapshot()
  }

  // 根据模板创建新的页面
  const createSlideByTemplate = (slide: Slide) => {
    // 建立 模板元素groupId、elId 和 新生成的元素的groupId、elId 之间的联系
    const { groupIdMap, elIdMap } = createElementIdMap(slide.elements)

    for (const element of slide.elements) {
      // 为基于模板新生成的元素分配id
      element.id = elIdMap[element.id]
      if (element.groupId) element.groupId = groupIdMap[element.groupId]
    }

    const newSlide = {
      ...slide,
      id: nanoid(10) // 为新生成的slide生成id
    }
    // 清空处于选中状态的元素id
    mainStore.setActiveElementIdList([])
    // 添加slide
    slidesStore.addSlide(newSlide)
    // 添加历史快照
    addHistorySnapshot()
  }

  // 尝试将剪贴板页面数据解密后添加到下一页（粘贴）
  const pasteSlide = () => {
    // 读取系统剪贴板的数据
    readClipboard().then(text => {
      // 粘贴剪贴板里面的文本
      pasteTextClipboardData(text, { onlySlide: true })
    }).catch(err => message.warning(err))
  }

  // 选中全部幻灯片
  const selectAllSlide = () => {
    /**
     * Array.from([], (item, index))
     * Array(slides.value.length) -> [empty * 3]
     */
    const newSelectedSlidesIndex = Array.from(Array(slides.value.length), (_, index) => index)
    mainStore.setActiveElementIdList([])
    mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
  }

  // 拖拽调整幻灯片顺序的同步数据
  const sortSlides = (newIndex: number, oldIndex: number) => {
    if (oldIndex === newIndex) return

    const _slides = JSON.parse(JSON.stringify(slides.value))
    const _slide = _slides[oldIndex]
    _slides.splice(oldIndex, 1)
    _slides.splice(newIndex, 0, _slide)
    slidesStore.setSlides(_slides)
    slidesStore.updateSlideIndex(newIndex)
  }

  // 将当前页面数据加密后复制到剪贴板
  const copySlide = () => {
    // 将幻灯片的页面数据使用crypto-js进行加密
    const text = encrypt(JSON.stringify({
      type: 'slides',
      data: selectedSlides.value // 已经被选中的幻灯片数据
    }))
    // 使用clipboard将文本复制到剪贴板
    copyText(text).then(() => {
      mainStore.setThumbnailsFocus(true)
    })
  }

  // 删除当前页，若将删除全部页面，则执行重置幻灯片操作
  const deleteSlide = (targetSlidesId = selectedSlidesId.value) => {
    // 若删除全部的幻灯片，则将幻灯片重置为一张空白的幻灯片
    if (slides.value.length === targetSlidesId.length) resetSlides()
    else slidesStore.deleteSlide(targetSlidesId)

    mainStore.updateSelectedSlidesIndex([])
    addHistorySnapshot()
  }

  // 将当前页复制后删除（剪切）
  // 由于复制操作会导致多选状态消失，故需要提前将需要删除的页面ID进行缓存
  const cutSlide = () => {
    const targetSlidesId = [...selectedSlidesId.value]
    copySlide()
    deleteSlide(targetSlidesId)
  }

  // 将当前页复制一份到下一页
  const copyAndPasteSlide = () => {
    // 将类数组转化为数组
    const slide = JSON.parse(JSON.stringify(currentSlide.value))
    addSlidesFromData([slide])
  }

  /**
   * 移动页面焦点
   * @param command 移动页面焦点命令：上移、下移
   */
  const updateSlideIndex = (command: string) => {
    if (command === KEYS.UP && slideIndex.value > 0) {
      if (activeElementIdList.value.length) mainStore.setActiveElementIdList([])
      slidesStore.updateSlideIndex(slideIndex.value - 1)
    }
    else if (command === KEYS.DOWN && slideIndex.value < slides.value.length - 1) {
      if (activeElementIdList.value.length) mainStore.setActiveElementIdList([])
      slidesStore.updateSlideIndex(slideIndex.value + 1)
    }
  }
  return {
    resetSlides,
    createSlide,
    createSlideByTemplate,
    pasteSlide,
    selectAllSlide,
    sortSlides,
    copySlide,
    cutSlide,
    deleteSlide,
    copyAndPasteSlide,
    updateSlideIndex
  }
}